import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import css from './runtime.less'
import Tab from '../components/tab/tab'
function EditRender({ env, data, inputs, outputs, slots, style: initStyle }: any) {
  const [activeKey, setActiveKey] = useState('content')
  const layers = data.layerList?.map?.((status: any, index: number) => {
    const id = status.id
    let title = status.title
    return {
      label: title,
      value: id
    }
  })
  let items: any[] = []
  if (layers && layers.length > 0) {
    items = [
      {
        label: '内容',
        value: 'content'
      },
      ...layers
    ]
  }
  let active = activeKey
  if (!Array.isArray(data.layerList) || data.layerList.length < 1 || !data.layerList.some((layer: any) => layer.id == active)) {
    active = 'content'
  }
  return (
    <div className={css['box']} style={{ ...(data.style || {}), width: initStyle.width, height: initStyle.height }}>
      {items && items.length > 0 ? <Tab actived={active} onChange={setActiveKey} items={items} /> : null}
      {slots[active]?.render?.()}
    </div>
  )
}

function RuntimeRender({ env, data, inputs, outputs, slots, style: initStyle }: any) {
  const containerRef = useRef<HTMLDivElement>(null)
  const [style, setStyle] = useState({})
  const observerRef = useRef<IntersectionObserver>()
  
  inputs['setStyle']((val, relOutput) => {
    const nStyle = { ...(style || {}), ...(val || {}) }
    setStyle(nStyle)
    relOutput['setStyleDone'](nStyle)
  })

  useEffect(() => {
    if (data.enableFade) {
      const container = containerRef.current
      if (!container) return
      if (!observerRef.current) {
        let threshold = Number(data.threshold)
        if (Number.isNaN(threshold)) {
          threshold = 0.2
        }
        if (threshold > 1) {
          threshold = 1
        }
        if (threshold < 0) {
          threshold = 0
        }

        observerRef.current = new IntersectionObserver(
          (entities) => {
            entities.forEach((entity) => {
              if (entity.isIntersecting) {
                outputs['onFadeIn']?.()
              } else {
                outputs['onFadeOut']?.()
              }
            })
          },
          { rootMargin: '0px 0px 0px 0px', threshold: threshold }
        )
      }
      observerRef.current.observe(container)
      return () => {
        observerRef.current?.unobserve?.(container)
      }
    }
  }, [data.enableFade])

  inputs['getStyle']((val, relOutput) => {
    relOutput['getStyleDone'](style)
  })

  return (
    <div ref={containerRef} className={css['box']} style={{ ...style ,width: initStyle.width, height: initStyle.height }}>
      <div className={css['content']}>{slots['content'].render()}</div>
      {data.layerList && data.layerList.length > 0
        ? data.layerList.map((layer: any) => {
            return (
              <div key={layer.id} className={css['layer']} style={{ zIndex: layer.zIndex || 0 }}>
                {slots[layer.id]?.render?.()}
              </div>
            )
          })
        : null}
    </div>
  )
}

export default function (props: any) {
  /** 运行时 */
  return props.env?.edit ? <EditRender {...props} /> : <RuntimeRender {...props} />
}
